package com.frinder.entity;

import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.dozer.DozerBeanMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * Created by frinder6 on 2016/10/24.
 * <p>
 * 接收 dt前端框架参数
 * &
 * 返回服务器数据到前端 dt框架
 * <p>
 * 参考博文：http://blog.csdn.net/chenjing502/article/details/38285291
 */
public class DataTables<T extends BaseEntity> {

    private static Logger logger = LoggerFactory.getLogger(DataTables.class);

    private static final DozerBeanMapper MAPPER = new DozerBeanMapper();

    static {
        MAPPER.setMappingFiles(Collections.singletonList("dozer.xml"));
    }

    /**
     * 返回 T
     *
     * @param tClass
     * @return
     * @throws Exception
     */
    public T getT(Class<T> tClass) throws Exception {
        T obj;
        if (null != target) {
            obj = MAPPER.map(target, tClass);
        } else {
            obj = tClass.newInstance();
        }
        obj.setSearchText(getSearchText());
        return obj;
    }

    /**
     * 获取当前页
     *
     * @return
     */
    public int getPage() {
        return (start + length) / length;
    }


    /**
     * 获取排序列
     *
     * @return
     */
    public String getOrderBy() {
        List<String> stringList = new ArrayList<>();
        if (null != order) {
            order.forEach(o -> {
                int index = o.get(Order.column) == null ? 0 : Integer.parseInt(o.get(Order.column).toString());
                int len = columns.size();
                if (index >= 0 && index <= (len - 1)) {
                    Object col = columns.get(index).get(Column.data);
                    if (null != col && !Strings.isNullOrEmpty(col.toString())) {
                        stringList.add(col + " " + o.get(Order.dir));
                    }
                }
            });
        }
        if (stringList.isEmpty()) {
            stringList.add("id ASC");
        }
        return Joiner.on(" , ").join(stringList).trim();
    }

    /**
     * 获取搜索文本
     *
     * @return
     */
    public String getSearchText() {
        return StringUtils.isEmpty(search) ? "" : search.get(Search.value);
    }

    /**
     * 构建响应结果并返回
     *
     * @param recordsTotal
     * @param recordsFiltered
     * @param data
     * @return
     */
    public DataTables<T> getResponse(int recordsTotal, int recordsFiltered, List data) {
        setRecordsTotal(recordsTotal);
        setRecordsFiltered(recordsFiltered);
        setData(data);
        return this;
    }


    /**
     * 请求&响应都需要属性
     */
    private int start = 0;

    private int length = 10;

    /**
     * 返回结果
     */
    private List<T> data;

    private int recordsTotal;

    private int recordsFiltered;

    /**
     * 请求参数
     */

    private long draw;

    private String pageNum;

    private List<Map<Column, Object>> columns;

    private List<Map<Order, Object>> order;

    private Map<Search, String> search;

    /**
     * 接收查询参数
     */
    private Map<String, Object> target;


    /**
     * 表格右上侧搜索框
     */
    public enum Search {
        value,
        regex
    }


    /**
     * 排序
     */
    public enum Order {
        column,
        dir
    }

    /**
     * 列
     */
    public enum Column {
        data,
        name,
        searchable,
        orderable,
        searchValue,
        searchRegex
    }


    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }

    public int getRecordsTotal() {
        return recordsTotal;
    }

    public void setRecordsTotal(int recordsTotal) {
        this.recordsTotal = recordsTotal;
    }

    public int getRecordsFiltered() {
        return recordsFiltered;
    }

    public void setRecordsFiltered(int recordsFiltered) {
        this.recordsFiltered = recordsFiltered;
    }

    public long getDraw() {
        return draw;
    }

    public void setDraw(long draw) {
        this.draw = draw;
    }

    public String getPageNum() {
        return pageNum;
    }

    public void setPageNum(String pageNum) {
        this.pageNum = pageNum;
    }

    public List<Map<Column, Object>> getColumns() {
        return columns;
    }

    public void setColumns(List<Map<Column, Object>> columns) {
        this.columns = columns;
    }

    public List<Map<Order, Object>> getOrder() {
        return order;
    }

    public void setOrder(List<Map<Order, Object>> order) {
        this.order = order;
    }

    public Map<Search, String> getSearch() {
        return search;
    }

    public void setSearch(Map<Search, String> search) {
        this.search = search;
    }

    public Map<String, Object> getTarget() {
        return target;
    }

    public void setTarget(Map<String, Object> target) {
        this.target = target;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.DEFAULT_STYLE);
    }
}
